import { PlayerManager } from "./Biz/PlayerManager";
import { RoomManager } from "./Biz/RoomManager";
import { ApiMsgEnum } from "./Common";
import { IApiGameStartReq, IApiGameStartRes, IApiPlayerJoinReq, IApiPlayerJoinRes, IApiPlayerListReq, IApiPlayerListRes, IApiRoomCreateReq, IApiRoomCreateRes, IApiRoomJoinReq, IApiRoomJoinRes, IApiRoomLeaveReq, IApiRoomLeaveRes, IApiRoomListReq, IApiRoomListRes } from "./Common/Api";
import { Connection, MyServer } from "./Core";
import { symlinkCommon } from "./Utils";

symlinkCommon();

declare module "./Core" {
    interface Connection {
        playerId: number
    }
}

const server = new MyServer({
    port: 9876
})

server.on("connection", (connection: Connection) => {
    console.log("player join!", server.connections.size)
})

server.on("disconnection", (connection: Connection) => {
    if (connection.playerId) {
        PlayerManager.Instance.removePlayer(connection.playerId);
        PlayerManager.Instance.syncPlayers();
        RoomManager.Instance.syncRooms();
        console.log("player leave!", PlayerManager.Instance.players.size)
    }
})

server.setApi(ApiMsgEnum.ApiPlayerJoin, (connection: Connection, data: IApiPlayerJoinReq): IApiPlayerJoinRes => {
    const { nickname } = data;
    const player = PlayerManager.Instance.createPlayer({ nickname, connection });
    connection.playerId = player.id
    PlayerManager.Instance.syncPlayers();
    return {
        player: PlayerManager.Instance.getPlayerView(player)
    }
})

server.setApi(ApiMsgEnum.ApiPlayerList, (connection: Connection, data: IApiPlayerListReq): IApiPlayerListRes => {
    return {
        list: PlayerManager.Instance.getPlayersView()
    }
})

server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, data: IApiRoomCreateReq): IApiRoomCreateRes => {
    if (connection.playerId) {
        const newRoom = RoomManager.Instance.createRoom(connection.playerId);
        const room = RoomManager.Instance.joinRoom(newRoom.rid, connection.playerId)
        if (room) {
            RoomManager.Instance.syncRooms();
            PlayerManager.Instance.syncPlayers();
            return {
                room: RoomManager.Instance.getRoomView(room)
            }
        } else {
            throw new Error("房间不存在")
        }
    } else {
        throw new Error("未登录")
    }
})

server.setApi(ApiMsgEnum.ApiRoomList, (connection: Connection, data: IApiRoomListReq): IApiRoomListRes => {
    return {
        list: RoomManager.Instance.getRoomsView()
    }
})

server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, { rid }: IApiRoomJoinReq): IApiRoomJoinRes => {
    if (connection.playerId) {
        const room = RoomManager.Instance.joinRoom(rid, connection.playerId)
        if (room) {
            RoomManager.Instance.syncRooms();
            RoomManager.Instance.syncRoom(rid);
            PlayerManager.Instance.syncPlayers();
            return {
                room: RoomManager.Instance.getRoomView(room)
            }
        } else {
            throw new Error("房间不存在")
        }
    } else {
        throw new Error("未登录")
    }
})

server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection, { }: IApiRoomLeaveReq): IApiRoomLeaveRes => {
    if (connection.playerId) {
        const player = PlayerManager.Instance.idMapPlayers.get(connection.playerId);
        if (player) {
            const rid = player.rid
            if (rid) {
                RoomManager.Instance.leaveRoom(player.rid, player.id)
                RoomManager.Instance.syncRooms();
                RoomManager.Instance.syncRoom(rid);
                PlayerManager.Instance.syncPlayers();
                return {
                }
            } else {
                throw new Error("玩家不在房间中")
            }
        } else {
            throw new Error("玩家不存在")
        }
    } else {
        throw new Error("未登录")
    }
})

server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, { }: IApiGameStartReq): IApiGameStartRes => {
    if (connection.playerId) {
        const player = PlayerManager.Instance.idMapPlayers.get(connection.playerId);
        if (player) {
            const rid = player.rid
            if (rid) {
                if (RoomManager.Instance.startRoom(player.rid, player.id)) {
                    RoomManager.Instance.syncRooms();
                    RoomManager.Instance.syncRoom(rid);
                    PlayerManager.Instance.syncPlayers();
                    return {
                    }
                } else {
                    throw new Error(`玩家${player.id}不是房主`)
                }
            } else {
                throw new Error("玩家不在房间中")
            }
        } else {
            throw new Error("玩家不存在")
        }
    } else {
        throw new Error("未登录")
    }
})

server.start().then(() => {
    console.log("wss server start!");
}).catch((e) => {
    console.log("wss server error!");

})

// const wss = new WebSocketServer({
//     port: 9876
// })

// let inputs = [];

// wss.on("connection", (socket) => {
//     socket.on("message", (buffer) => {
//         // console.log("message:", buffer.toString())
//         const str = buffer.toString();
//         try {
//             const msg = JSON.parse(str);
//             const { name, data } = msg;
//             if (name === ApiMsgEnum.MsgClientSync) {
//                 console.log("input:", buffer.toString())
//                 const { frameId, input } = data;
//                 inputs.push(input)
//             }
//         } catch (error) {
//             console.log(error)
//         }
//     })

//     setInterval(() => {
//         const temp = [...inputs];
//         inputs = [];
//         const obj = {
//             name: ApiMsgEnum.MsgServerSync,
//             data: {
//                 inputs: temp
//             }
//         }

//         socket.send(JSON.stringify(obj));
//     }, 33)

//     // const obj = {
//     //     name: "test",
//     //     data: "i am test"
//     // }

//     // socket.send(JSON.stringify(obj));
// })

// wss.on("listening", () => {
//     console.log("wss服务已开启！")
// })